﻿using DAO.Common.ViewModels;
using AutomationView.Views;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Linq;
using System;
using DAO;

namespace AutomationView
{
    public abstract class CustomersEngine: BaseEngine
    {
        protected CustomersEngine()
        {
            Handlers.Add(ViewState.Customers.Start, StartStrategy);
            Handlers.Add(ViewState.Customers.Load, LoadStrategy);
            Handlers.Add(ViewState.Customers.Adding, AddingStrategy);

            States.Add(ViewState.Customers.Start, new List<Operation> { });
            States.Add(ViewState.Customers.Load, new List<Operation> { 
                Operations.Add, Operations.Close, Operations.Delete, Operations.Sort
            });
            States.Add(ViewState.Customers.Adding, new List<Operation> { Operations.Refresh, Operations.Return });
        }

        #region Const

        public class Operations
        {
            public static readonly Operation Refresh = new Operation("Refresh");
            public static readonly Operation Add = new Operation("Add");
            public static readonly Operation Return = new Operation("CancelAdd");
            public static readonly Operation Delete = new Operation("Delete");
            public static readonly Operation<string> Sort = new Operation<string>("Sort");
            public static readonly Operation Close = new Operation("Close");
        }
        #endregion

        #region Current state

        protected bool Success { get; set; }

        public IList<CustomerViewModel> Customers { get; protected set; }

        #endregion

        protected abstract ViewState StartStrategy(Operation action);
                           
        protected abstract ViewState LoadStrategy(Operation action);
                          
        protected abstract ViewState AddingStrategy(Operation action);
    }


    class FormCustomersEngine: CustomersEngine
    {
        Form form;

        #region Compnents
        
        /// <summary>
        /// Supply customers dataGridView's data source 
        /// </summary>
        protected DataGridView CustomersGridView
        {
            get
            {
                return form.Find("customersGridView") as DataGridView;
            }
        }
        #endregion

        #region Implemented

        public override void Start()
        {
            this.form = new CustomersEngineView();

            form.Find("btnAddCustomer").Click += (o, e) => Accept(Operations.Add);

            this.CustomersGridView.ColumnHeaderMouseClick += (o, e) =>
            {
                Operations.Sort.Argument = this.CustomersGridView.Columns[e.ColumnIndex].DataPropertyName;
                Accept(Operations.Sort);
            };

            form.FormClosed += (o, e) => Accept(Operations.Close);
            SimpleFactory.GetObject<Helper.FormRenderer>().Show(form);  //***Shouldn't call show() directly
            base.Start();
        }

        protected override ViewState StartStrategy(Operation action)
        {
            return LoadData();
        }

        protected override ViewState LoadStrategy(Operation action)
        {
            if (action == Operations.Add)
            {
                var subEngine = SimpleFactory.GetObject<FormAddCustomerEngine>();
                this.CurrentSubEngine = subEngine;

                subEngine.StateChanged += state =>
                {
                    if (CurrentSubEngine.CurrentState == ViewState.Common.End)
                    {
                        //if (subEngine.Success) this.Accept(Operations.Refresh);

                        this.Accept(subEngine.Success ? Operations.Refresh : Operations.Return);
                    }
                };
                subEngine.Start();

                return ViewState.Customers.Adding;
            }
            else if (action == Operations.Sort)
            {
                var sortFunc = AutomationView.Metadata.CustomerViewModel.GetProperty(Operations.Sort.Argument);
               
                this.CustomersGridView.DataSource = base.Customers.OrderBy(sortFunc).ToArray();
            }
            else if (action == Operations.Close)
                return ViewState.Customers.End;

            return ViewState.Customers.Load;
        }

        protected override ViewState AddingStrategy(Operation action)
        {
            if (action == Operations.Refresh)
            {
                return ViewState.Customers.Start;   //Will reload data
            }

            if (CurrentSubEngine.CurrentState != ViewState.Common.End)
                this.CurrentSubEngine.Accept(AddCustomerEngine.Operations.Cancel);

            return ViewState.Customers.Load;    //return to load state
        }

        protected override void End()
        {
            //MessageBox.Show("你真强！欢迎下次光临。");
            Application.Exit();
        }
        #endregion


        private ViewState LoadData()
        {
            this.Customers = SimpleFactory.GetObject<ICustomerDao>().GetAllCustomers().Select(c => new CustomerViewModel(c)).ToArray();
            this.CustomersGridView.DataSource = Customers;
            return ViewState.Customers.Load;
        }
    }


}
